// FrogFavoriteDialog.cpp : Implementation of CFrogFavoriteDialog

#include "stdafx.h"
#include "FrogFavoriteDialog.h"
#include "FrogMessageBox.h"
#include "..\FilerFrogUtils\FilerFrogUtils.h"

#pragma warning(disable:4482)

// CFrogFavoriteDialog

CFrogFavoriteDialog::CFrogFavoriteDialog():
CFrogBaseDialog(NULL),
himl(NULL)
{
	SetIcon(m_MenuItemsHolder.m_Icons[MenuPics::ICON_FAV]);
}

LRESULT CFrogFavoriteDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	CFrogBaseDialog::OnInitDialog(uMsg, wParam, lParam, bHandled);

	himl = NULL;

	HANDLE hIcon = m_MenuItemsHolder.m_Icons[MenuPics::ICON_FAV];
	SendMessage(WM_SETICON, ICON_BIG, (LPARAM)hIcon);
	SendMessage(WM_SETICON, ICON_SMALL, (LPARAM)hIcon);

	// Gets Existing List
	list<FileOps> favlist;
	GetFavoritesList(favlist);

	HWND listFrom = GetDlgItem(IDC_LIST_FROM);
	HWND listTo = GetDlgItem(IDC_LIST_TO);

	himl = ImageList_Create(16,16, ILC_COLOR32 | ILC_MASK, 0, 8);

	for (int i=0; i < FileOps::None; i++)
	{
		ImageList_AddIcon(himl, m_MenuItemsHolder.m_Icons[m_MenuItemsHolder.m_CmdIcon[(FileOps)i]]);
	}

	ListView_SetImageList(listFrom, himl, LVSIL_SMALL);
	ListView_SetImageList(listTo, himl, LVSIL_SMALL);

	LVCOLUMN colData;
	ZeroMemory(&colData, sizeof(colData));
	colData.mask = LVCF_WIDTH;
	colData.cx = 230;

	ListView_InsertColumn(listFrom, 0, &colData);
	ListView_InsertColumn(listTo, 0, &colData);

	int posFrom = 0;
	int posTo = 0;

	for (int i=0; i < FileOps::About; i++)
	{
		list<FileOps>::iterator it;
		bool itemExists = false;

		for (it = favlist.begin(); it != favlist.end();  ++it)
		{
			int num = (int)*it;

			if (num == i && i != FileOps::MenuSeparator)
			{
				itemExists = true;
				break;
			}
		}

		LVITEM item;
		ZeroMemory(&item, sizeof(item));			

		item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
		item.iItem = i;
		item.lParam = i;

		wchar_t buffer[256];
		wcscpy_s(buffer, 256, m_MenuItemsHolder.m_CmdText[(FileOps)i].c_str());
		item.pszText = buffer;
		item.iImage = i;

		if (!itemExists)
		{
			item.iItem = posFrom;
			ListView_InsertItem(listFrom, &item);
			posFrom++;
		}
	}

	list<FileOps>::iterator it;

	for (it = favlist.begin(); it != favlist.end();  ++it)
	{
		int i = (int)*it;

		LVITEM item;
		ZeroMemory(&item, sizeof(item));			

		item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
		item.iItem = posTo;
		item.lParam = i;
		wchar_t buffer[256];
		wcscpy_s(buffer, 256, m_MenuItemsHolder.m_CmdText[(FileOps)i].c_str());
		item.pszText = buffer;
		item.iImage = i;

		ListView_InsertItem(listTo, &item);

		posTo++;				
	}

	return 0;
}

LRESULT CFrogFavoriteDialog::OnClickedOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	bHandled = TRUE;

	SaveFavoritesData();

	EndDialog(wID);
	return 0;
}

LRESULT CFrogFavoriteDialog::OnClickedAdd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	HWND listFrom = GetDlgItem(IDC_LIST_FROM);
	HWND listTo = GetDlgItem(IDC_LIST_TO);

	LVITEM item;
	wchar_t buffer[256];

	int index = -1;

	list<int> itemsToRemove;

	while ((index = ListView_GetNextItem(listFrom, index, LVNI_SELECTED)) != -1)
	{
		ZeroMemory(&item, sizeof(item));			
		item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
		item.iItem = index;
		item.pszText = buffer;
		item.cchTextMax = 256;
		ListView_GetItem(listFrom, &item);

		item.iItem = ListView_GetItemCount(listTo); // index

		// MessageBox(item.pszText, 0, 0);
		ListView_InsertItem(listTo, &item);

		// Menu Separator will be kept in original list
		if (item.lParam != FileOps::MenuSeparator)
		{
			itemsToRemove.push_back(index);
		}
	}

	itemsToRemove.sort();
	itemsToRemove.reverse();

	list<int>::iterator it;

	for (it = itemsToRemove.begin(); it != itemsToRemove.end(); ++it)
	{
		ListView_DeleteItem(listFrom, *it);
	}

	::SetFocus(listFrom);

	return 0;
}

LRESULT CFrogFavoriteDialog::OnClickedRemove(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	HWND listFrom = GetDlgItem(IDC_LIST_FROM);
	HWND listTo = GetDlgItem(IDC_LIST_TO);

	LVITEM item;
	wchar_t buffer[256];

	int index = -1;

	list<int> itemsToRemove;

	while ((index = ListView_GetNextItem(listTo, index, LVNI_SELECTED)) != -1)
	{
		ZeroMemory(&item, sizeof(item));			
		item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
		item.iItem = index;
		item.pszText = buffer;
		item.cchTextMax = 256;
		ListView_GetItem(listTo, &item);

		// MessageBox(item.pszText, 0, 0);

		// Already in the list so we wont add him
		if (item.lParam != FileOps::MenuSeparator)
		{
			ListView_InsertItem(listFrom, &item);
		}

		itemsToRemove.push_back(index);
	}

	itemsToRemove.sort();
	itemsToRemove.reverse();

	list<int>::iterator it;

	for (it = itemsToRemove.begin(); it != itemsToRemove.end(); ++it)
	{
		ListView_DeleteItem(listTo, *it);
	}

	::SetFocus(listTo);

	return 0;
}

LRESULT CFrogFavoriteDialog::OnClickedUp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{	
	HWND listTo = GetDlgItem(IDC_LIST_TO);
	int index = ListView_GetNextItem(listTo, -1, LVNI_SELECTED);

	if (index > 0)
	{
		FilerFrogUtils::SwapItems(listTo, index, index - 1);
	}

	::SetFocus(listTo);

	return 0;
}

LRESULT CFrogFavoriteDialog::OnClickedDown(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	HWND listTo = GetDlgItem(IDC_LIST_TO);
	int index = ListView_GetNextItem(listTo, -1, LVNI_SELECTED);
	int count = ListView_GetItemCount(listTo);

	if (index != -1 && index < count - 1)
	{
		FilerFrogUtils::SwapItems(listTo, index, index + 1);
	}

	::SetFocus(listTo);

	return 0;
}


void CFrogFavoriteDialog::SaveFavoritesData()
{
	HWND listTo = GetDlgItem(IDC_LIST_TO);

	LVITEM item;
	wchar_t buffer[256];

	int index = -1;
	list<FileOps> itemsToAdd;

	while ((index = ListView_GetNextItem(listTo, index, LVNI_ALL)) != -1)
	{
		ZeroMemory(&item, sizeof(item));			
		item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
		item.iItem = index;
		item.pszText = buffer;
		item.cchTextMax = 256;
		ListView_GetItem(listTo, &item);

		itemsToAdd.push_back((FileOps)item.lParam);
	}

	HKEY hkey;
	DWORD dwDisposition; 
	DWORD dwType, dwSize;

	long lResult = RegCreateKeyEx(
		HKEY_CURRENT_USER,
		TEXT("Software\\FilerFrog"),
		0,
		NULL,
		REG_OPTION_NON_VOLATILE,
		KEY_ALL_ACCESS,
		NULL,
		&hkey,
		&dwDisposition);

	wchar_t szValue[1024];
	ZeroMemory(szValue, sizeof(szValue));

	int size = 0;

	list<FileOps>::iterator it;

	for (it = itemsToAdd.begin(); it != itemsToAdd.end(); ++it)
	{
		wchar_t buffer[256];
		ZeroMemory(buffer, sizeof(buffer));

		unsigned int num = (unsigned int)*it;
		swprintf_s(buffer, 256, L"%u", num);

		size_t bytesToCopy = lstrlen(buffer)+1;

		memcpy_s(szValue + size, sizeof(szValue) - size * sizeof(wchar_t), buffer, bytesToCopy * sizeof(wchar_t));

		size += lstrlen(buffer)+1;
	}

	size = size * sizeof(wchar_t);

	if (lResult == ERROR_SUCCESS)
	{		
		dwType = REG_MULTI_SZ;		
		dwSize = size;		
		lResult = RegSetValueEx(hkey, L"Favorites Items", 0, dwType, (PBYTE)szValue, dwSize);
		RegCloseKey(hkey);
	}
}

void CFrogFavoriteDialog::GetFavoritesList(list<FileOps>& list)
{
	list.clear();

	HKEY hkey;
	DWORD dwType, dwSize;

	long lResult = RegOpenKeyEx(
		HKEY_CURRENT_USER,
		TEXT("Software\\FilerFrog"),
		0,
		KEY_QUERY_VALUE,						
		&hkey);

	wchar_t szValue[1024];
	wchar_t* pValue = szValue;
	ZeroMemory(szValue, sizeof(szValue));

	if (lResult == ERROR_SUCCESS)
	{
		dwType = REG_NONE;		
		dwSize = sizeof(szValue);
		RegQueryValueEx(hkey, L"Favorites Items", 0, &dwType, (LPBYTE)szValue, &dwSize);

		if (dwType == REG_MULTI_SZ)
		{
			size_t offset = 0;
			size_t bytesCount = 0;

			while (bytesCount < dwSize && pValue[0] != L'\0')
			{
				wchar_t buffer[256];
				wcscpy_s(buffer, 256, pValue);

				int num = _wtoi(buffer);

				if (num >= 0 && num < FileOps::None)
				{
					FileOps fileOps = (FileOps)num;
					list.push_back(fileOps);
				}

				offset = wcslen(buffer) + 1;
				bytesCount += offset*2;
				pValue = pValue + offset;
			}
		}
	}

	list.unique();
}